/**
 * Copyright(c) 2014 Xunton Solutions
 *
 * History:
 *   15-6-7 下午6:22 Created by dwzhang
 */
package com.jade.framework.base.util;

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.Iterator;
import javax.imageio.ImageIO;
import javax.imageio.ImageReader;

/**
 * 图片处理工具。
 *
 * @author <a href="mailto:dwzhang@xunton.com">dwzhang</a> 
 * @version 1.0 15-6-7 下午6:22
 */
public class ImageUtils
{
    public static File getThumbImage(File srcImage, File thumbImage, String format, int width, int height)
            throws IOException
    {
        return getThumbImage(srcImage, thumbImage, format, width, height, true);
    }

    public static File getThumbImage(File srcImage, File thumbImage, String format, int width, int height,
                                     boolean ratio)
            throws IOException
    {
        BufferedImage source = ImageIO.read(srcImage);
        if (ratio) {
            // targetW，targetH分别表示目标长和宽
            double sx = (double) width / source.getWidth();
            double sy = (double) height / source.getHeight();
            //则将下面的if else语句注释即可
            if (sx > sy) {
                sx = sy;
                width = (int) (sx * source.getWidth());
            }
            else {
                sy = sx;
                height = (int) (sy * source.getHeight());
            }
        }
        /*新生成结果图片*/
        BufferedImage target = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        target.getGraphics().drawImage(source.getScaledInstance(width, height, java.awt.Image.SCALE_SMOOTH), 0, 0,
                null);


//        if (type == BufferedImage.TYPE_CUSTOM) { //handmade
//            ColorModel cm = source.getColorModel();
//            WritableRaster raster = cm.createCompatibleWritableRaster(width, height);
//            boolean alphaPremultiplied = cm.isAlphaPremultiplied();
//            target = new BufferedImage(cm, raster, alphaPremultiplied, null);
//        }
//        else {
//            target = new BufferedImage(width, height, type);
//        }
//        Graphics2D g = target.createGraphics();
//        //smoother than exlax:
//        g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
//        g.drawRenderedImage(source, AffineTransform.getScaleInstance(sx, sy));
//        g.dispose();


        if (StringUtilsEx.isBlank(format)) {
            format = "JPEG";
        }

//        try {
//            /*输出到文件流*/
//            FileOutputStream newimage = new FileOutputStream(thumbImage);
//            JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(newimage);
//            JPEGEncodeParam jep = JPEGCodec.getDefaultJPEGEncodeParam(target);
//            /* 压缩质量 */
//            jep.setQuality(1f, true);
//            encoder.encode(target, jep);
//           /*近JPEG编码*/
//            newimage.close();
//        }
//        catch (Exception e) {
//            e.printStackTrace();
//        }

        ImageIO.write(target, format, thumbImage);
        return thumbImage;
    }

    public static File getThumbImage2(InputStream srcImage, File thumbImage, String format, int width, int height)
            throws IOException
    {
        format = StringUtilsEx.isBlank(format) ? getFormatName(srcImage) : format;
        BufferedImage source = ImageIO.read(srcImage);
        return getThumbImage2(source, thumbImage, format, width, height);
    }

    public static File getThumbImage2(File srcImage, File thumbImage, String format, int width, int height)
            throws IOException
    {
        format = StringUtilsEx.isBlank(format) ? getFormatName(srcImage) : format;
        BufferedImage source = ImageIO.read(srcImage);
        return getThumbImage2(source, thumbImage, format, width, height);
    }


    protected static File getThumbImage2(BufferedImage source, File thumbImage, String format, int width, int height)
            throws IOException
    {
        String defaultFormat = "jpeg";
        format = StringUtilsEx.isBlank(format) ? defaultFormat : format;


        int srcWidth = source.getWidth();
        int srcHeight = source.getHeight();
        int scaleWidth = width, scaleHeight = height;
        double sx = (double) width / srcWidth;
        double sy = (double) height / srcHeight;
        if (sx <= 1 && sy <= 1) {
            int topx = 0, topy = 0;
            if (sx < sy) {
                sx = sy;
                scaleWidth = (int) (sx * srcWidth);
                topx = (scaleWidth - width) / 2;
            }
            else {
                sy = sx;
                scaleHeight = (int) (sy * srcHeight);
                topy = (scaleHeight - height) / 2;
            }


            BufferedImage target = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
            target.getGraphics().drawImage(
                    source.getScaledInstance(scaleWidth, scaleHeight, java.awt.Image.SCALE_SMOOTH), 0, 0, width, height,
                    topx, topy, width + topx, height + topy, null);
            ImageIO.write(target, format, thumbImage);
            return thumbImage;
        }
        else {
            int firstX = 0, firstY = 0, secondX = 0, sencondY = 0;
            int writeWidth = width, writeHeight = height;
            if (sx > 1) {
                firstX = (width - srcWidth) / 2;
            }
            else {
                writeHeight = srcHeight;
                secondX = (srcWidth - width) / 2;
            }
            if (sy > 1) {
                firstY = (height - srcHeight) / 2;
            }
            else {
                writeWidth = srcWidth;
                sencondY = (srcHeight - height) / 2;
            }
            BufferedImage target = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
            target.getGraphics().drawImage(source, firstX, firstY, writeWidth + firstX, writeHeight + firstY,
                    secondX, sencondY, secondX + writeWidth, sencondY + writeHeight, null);
            ImageIO.write(target, format, thumbImage);
            return thumbImage;
        }
    }

    public static final String getFormatName(File image)
            throws IOException
    {
        Iterator<ImageReader> readers =  ImageIO.getImageReaders(ImageIO.createImageInputStream(image));
        while (readers.hasNext()) {
            ImageReader reader = readers.next();
            return reader.getFormatName();
        }
        return null;
    }

    public static final String getFormatName(InputStream in)
            throws IOException
    {
        Iterator<ImageReader> readers =  ImageIO.getImageReaders(in);
        while (readers.hasNext()) {
            ImageReader reader = readers.next();
            return reader.getFormatName();
        }
        return null;
    }
}
